﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using T4UtilityBelt.UxDesigns.Controls;
using T4UtilityBelt.UxDesigns.Controls.Renderers;

using T4UtilityBelt.UxDesigns.Screens.Renders;
using T4UtilityBelt.Writers;

namespace T4UtilityBelt.UxDesigns
{
    public abstract class View
    {
        [XmlAttribute]
        public string Name
        {
            get
            {
                if (_name == null)
                {
                    return "";
                }
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        internal virtual void FixModel(T4UtilityBelt.DataDesigns.EntityModel model)
        {
        }

        public abstract void RenderParentClass(CodeWriter writer);

        public abstract string ToStringNamespace(Platforms platform);

        public abstract void RenderCode(CodeWriter writer);

        public abstract string ToStringCode(Platforms platform);

        public abstract void RenderControls(CodeWriter writer);

        public abstract string ToStringControls(Platforms platform);

        private readonly ControlCollection _controls = new ControlCollection();
        private string _name;

        public virtual ControlCollection Controls
        {
            get { return _controls; }
        }

        public virtual IEnumerable<Control> AllControls()
        {
            if (Controls.Count > 0)
            {
                foreach (Control c in Controls)
                {
                    yield return c;
                    foreach (Control cc in c.AllControls())
                    {
                        yield return cc;
                    }
                }
            }
        }

    }

    public abstract class View<TView, TRenderer> : View
        where TView : View<TView, TRenderer>
        where TRenderer : class, IViewRenderer<TView, TRenderer>
    {
        #region Rendering

        protected TRenderer CreateControlRenderer(Platforms platform)
        {
            return RendererHelper.CreateRenderer<TRenderer>(platform);
        }

        #endregion Rendering

        public sealed override void RenderParentClass(CodeWriter writer)
        {
            Contract.Assert(writer != null);


            CreateControlRenderer(writer.Platform).RenderParentClass(this as TView, writer);
        }

        public sealed override string ToStringNamespace(Platforms platform)
        {
            CodeWriter writer = new CodeWriter(platform);
            RenderParentClass(writer);
            return writer.ToString();
        }

        public sealed override void RenderCode(CodeWriter writer)
        {
            CreateControlRenderer(writer.Platform).RenderCode(this as TView, writer);
        }

        public sealed override string ToStringCode(Platforms platform)
        {
            CodeWriter writer = new CodeWriter(platform);
            RenderCode(writer);
            return writer.ToString();
        }

        public sealed override void RenderControls(CodeWriter writer)
        {
            CreateControlRenderer(writer.Platform).RenderControls(this as TView, writer);
        }

        public sealed override string ToStringControls(Platforms platform)
        {
            CodeWriter writer = new CodeWriter(platform);
            RenderControls(writer);
            return writer.ToString();
        }

    }
}
